#pragma once;

#define DATA_IN_RANGE_INCLUDE(val, minval, maxval, defaultval)		((val) >= (minval) && (val) <= (maxval) ? (val) : (defaultval))

#define DATA_IN_RANGE_EXCLUDE(val, minval, maxval, defaultval)		((val) > (minval) && (val) < (maxval) ? (val) : (defaultval))

#include <Windows.h>
#include <assert.h>
#include <vector>
#include <string>

namespace ConfigUtil{

	inline int ReadConfigSectionKeys(std::vector<std::string>& keys, const char* szSection, const char* szConfig)
	{
		keys.clear();
		const int max_str = 4096;
		char szTemp[max_str];
		DWORD uReadLen = ::GetPrivateProfileSection(szSection, szTemp, max_str, szConfig);

		for(size_t i = 0; i<uReadLen;)
		{
			std::string record = szTemp+i;
			std::string name = record.substr(0, record.find('='));
			keys.push_back(name);
			i+= record.length() + 1;
		}

		return (int)keys.size();
	}

	inline double GetPrivateProfileDouble(const char* szSection, const char* szKey, double dlDefaultValue, const char* szFileName, double dlExcludeInf, double dlExcludeUpper)
	{
		assert(dlDefaultValue > dlExcludeInf && dlDefaultValue < dlExcludeUpper);

		const int max_str = 256;
		char szTemp[max_str];
		char szDoubleTemp[max_str];
		sprintf_s(szDoubleTemp, max_str, "%.12f", dlDefaultValue);	
		::GetPrivateProfileString(szSection, szKey, szDoubleTemp, szTemp, max_str, szFileName);

		double ret = atof(szTemp);
		ret = DATA_IN_RANGE_EXCLUDE(ret, dlExcludeInf, dlExcludeUpper, dlDefaultValue);
		return ret;
	}

	inline int GetPrivateProfileInt(const char* szSection, const char* szKey, int iDefaultValue, const char* szFileName)
	{
		return ::GetPrivateProfileInt(szSection, szKey, iDefaultValue, szFileName);
	}

	inline int GetPrivateProfileInt(const char* szSection, const char* szKey, int iDefaultValue, const char* szFileName, int iExcludeInfVal, int iExcludeUppVal)
	{
		assert(iExcludeInfVal < iDefaultValue && iDefaultValue < iExcludeUppVal);

		int val = GetPrivateProfileInt(szSection, szKey, iDefaultValue, szFileName);
		return DATA_IN_RANGE_EXCLUDE(val, iExcludeInfVal, iExcludeUppVal, iDefaultValue);
	}

	inline std::string GetPrivateProfileString(const char* szSection, const char* szKey, const char* szDefaultValue, const char* szFileName)
	{
		const int max_str = 256;
		char szTemp[max_str];
		::GetPrivateProfileString(szSection, szKey, szDefaultValue, szTemp, max_str, szFileName);
		return szTemp;
	}

	inline std::vector<std::string> GetPrivateProfileStrings(const char* szSection, const char* szKey, char cSeperator, const char* szFileName)
	{
		std::vector<std::string> vszValues;

		std::string szWholeVal = GetPrivateProfileString(szSection, szKey, "", szFileName);

		std::string::size_type beginPos = 0;
		while(true)
		{
			std::string::size_type findPos = szWholeVal.find(cSeperator, beginPos);
			std::string val = szWholeVal.substr(beginPos, findPos);
			vszValues.push_back(val);

			if(findPos == std::string::npos)
				break;
			beginPos = findPos + 1;
		}

		return vszValues;
	}

}	//end namespace ConfigUtil

